/**
 * 该类用于把ui中的参数放在算法的数据结构中
 * ui中的参数为Scene、RayTracingParameter，需要将其中的数据存入SceneField、SceneConfiguration中
 */

#ifndef UI_RAY_TRACING_PROCESSOR
#define UI_RAY_TRACING_PROCESSOR

// #include "FluxMapParameter.h"

#include <boost/json.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>

#include <vector_types.h>

#include <memory>

namespace solar
{
    class RayTracingPipeline;
    class SceneField;
    class SceneConfiguration;
    class Scene;
    class RayTracingParameter;
    class TopoTreeNode;
    class Para;
    class RayTracingProcessor
    {
        public:
            RayTracingProcessor();
            void setRayTracingPipeline(std::shared_ptr<RayTracingPipeline> raytracing_pipeline);

            [[nodiscard]] auto getField() const -> std::shared_ptr<SceneField> { return field_; }
            [[nodiscard]] auto getConfig() const -> std::shared_ptr<SceneConfiguration>
            {
                return config_;
            }

            // bool rayTracing();  // 执行rayTracing
            // bool plotFluxMap();

            /**
             * 从scene、simulation_paras中加载数据
             */
            // 根据Scene和RayTracingParameter设置RayTracingPipeline中的field等参数
            auto updateRayTracingPipelineData(std::shared_ptr<Scene> scene,
                                              std::shared_ptr<RayTracingParameter> simulation_paras)
                -> bool;

            auto loadField(std::shared_ptr<SceneField>& field, std::shared_ptr<Scene> scene,
                           std::shared_ptr<RayTracingParameter> simulation_paras) -> bool;

            auto loadConfig(std::shared_ptr<SceneConfiguration>& config,
                            std::shared_ptr<Scene> scene,
                            std::shared_ptr<RayTracingParameter> simulation_paras) -> bool;

            auto loadCloudFilePath() -> bool;
            auto setGrid(std::shared_ptr<SceneField>& field,
                         std::shared_ptr<RayTracingParameter> simulation_paras) -> bool;
            // 其中sunray是field中的一个Sunray类型的属性，这个函数从config中读取相关数据写到field的sunray中
            auto setSunray(std::shared_ptr<SceneField>& field,
                           std::shared_ptr<SceneConfiguration> config) -> bool;
            void setHelioAndRevRecursively(
                std::shared_ptr<SceneField>& field, TopoTreeNode*& root,
                float3
                    position); // 在TopoTree中递归，找到一个helio就加载一个helio，找到一个rev就加载一个rev
            void setOneHeliostat(std::shared_ptr<SceneField>& field, Para*& para, float3 position);
            void setOneReceiver(std::shared_ptr<SceneField>& field, Para*& para, float3 position);

            /**
             * TODO::从文件中加载数据，暂时保留-----测试时间
             * 从文件中加载数据
             */
            auto updateRayTracingPipelineData(std::string file_path,
                                              std::shared_ptr<RayTracingParameter> simulation_paras)
                -> bool; // 根据json文件设置RayTracingPipeline中的各个参数
            auto loadField(std::shared_ptr<SceneField>& field, std::string file_path,
                           std::shared_ptr<RayTracingParameter> simulation_paras) -> bool;
            auto loadConfig(std::shared_ptr<SceneConfiguration>& config, std::string file_path,
                            std::shared_ptr<RayTracingParameter> simulation_paras) -> bool;

            auto read_json(std::shared_ptr<SceneConfiguration>& config,
                           std::shared_ptr<SceneField>& field, std::string file_path) -> bool;
            void setConfigFromJSON(std::shared_ptr<SceneConfiguration>& config,
                                   boost::property_tree::ptree tree);
            void setFieldFromJSON(std::shared_ptr<SceneField>& field,
                                  boost::property_tree::ptree tree);
            void setReceiverFromJSON(std::shared_ptr<SceneField>& field,
                                     boost::property_tree::ptree tree);
            void setHeliostatFromJSON(std::shared_ptr<SceneField>& field,
                                      boost::property_tree::ptree tree);
            void setGridFromJSON(std::shared_ptr<SceneField>& field,
                                 boost::property_tree::ptree tree);
            /**
             * 公用方法
             */
            void
            setConfigFromRayTracingParameter(std::shared_ptr<SceneConfiguration>& config,
                                             std::shared_ptr<RayTracingParameter> simulation_paras);
            // ResultData& getResultData();

        private:
            std::shared_ptr<RayTracingPipeline> raytracing_pipeline_; // 执行光追算法的对象
            std::shared_ptr<SceneField> field_;
            std::shared_ptr<SceneConfiguration> config_;
    };
} // namespace solar

#endif
